import math
import time
import pygame
from library import Vector
from pylibrary import Actor
import display
try:
    import stackless
except ImportError:
    print "no stackless"

class SpaceShip(Actor):
    rotx_vel = 0
    rotx_acc = 0
    last_xpoint = 0
    anglex = 0
    anglez = 0
    clock = pygame.time.Clock()
    #screen = display.Camera(self)

    def __init__(self, channel, position=(0,0,0)):
        self.piover180 = math.pi/180
        self.piover2 = math.pi/2
        self.position = Vector(*position)
        Actor.__init__(self)
        self.up = Vector(0, 1, 0)
        self.target = Vector(0, 0, -1)
        self.right = Vector(1, 0, 0)
        self.actions = {'turnx': self.rotatx, 'draw': self.draw}
        self.xchannel = stackless.channel()
        self.zchannel = stackless.channel()
        stackless.tasklet(self.rotx)(self.xchannel)
        self.display = display.Camera(self)

    def draw(self):
        self.display.set_position()
        self.display.draw()

    def process_message(self, action, *args):
        #print args
        self.actions[action](*args)

    def rotatex(self, point):
        elapsed = self.clock.tick()
        self.rotx_acc = self.last_xpoint - point
        self.rotx_vel += elapsed / self.rotx_acc
        self.anglex += elapsed / self.rotx_vel
        self._rotatex()
        self.last_xpoint = point

    def rotatx(self, point):
        self.xchannel.send(point)

    def _rotatex(self, angle):
        angle = angle * self.piover180
        up = self.up.copy()
        target = self.target.copy() # possibly not needed just use self.target
        cosBeta  = math.cos(angle)
        cosAlpha = math.cos(self.piover2 - angle)
        self.up.x = cosBeta * up.x + cosAlpha * target.x
        self.up.y = cosBeta * up.y + cosAlpha * target.y
        self.up.z = cosBeta * up.z + cosAlpha * target.z
        cosAlpha = math.cos(self.piover2 + angle)
        self.target.x = cosBeta * target.x + cosAlpha * up.x
        self.target.y = cosBeta * target.y + cosAlpha * up.y
        self.target.z = cosBeta * target.z + cosAlpha * up.z

    def rotx(self, channel):
        vel = 0
        angle = 0
        clock = pygame.time.Clock()
        pygame.time.delay(5)
        while 1:
            point = channel.receive()
            elapsed = clock.tick()
            if vel <= point:
                acc = (point - vel) * elapsed/10000.
                vel += acc * (elapsed)
            else:
                acc = 0
                vel = point
            #vel += acc * (elapsed)
            #angle += vel * (elapsed / 1000.)
            #print acc, vel#, angle
            self._rotatex(vel)

# class SpaceShip(object):
#     def __init__(self, position, channels):
#         self.position = Vector(position)
#         self.up = Vector((0,1,0))
#         self.target = Vector((0,0,-1))
#         self.right = Vector((1,0,0))
#         self.acceleration = 0
#         self.velocity = 0
#         self.angle = 0
#         self.piover180 = math.pi/180
#         self.piover2 = math.pi/2
#         self.channel = stackless.channel()
#         #self.move = stackless.tasklet(self.move)
#         #print self.move
#         self.rotatingx = False
#         self.rotatingz = False
#         stackless.tasklet(self.message_loop)()
#
#     def message_loop(self):
#         actions = {'turnx': self.rotatex, 'turny': self.rotatey,
#                    'stopx': self.stopx, 'stopy': self.stopy, 'move': self.move}
#         while 1:
#             action, args = self.channel.receive()
#             actions[action](args)
#
#
#
#
# #     def move(self):
# #         start_time = time.time()
# #         while 1:
# #             last_time = (self.channels['move'].receive() - start_time)
# #             if -0.1 <= self.velocity <= 0.1:
# #                 self.velocity += self.acceleration/last_time
# #             else:
# #                 self.velocity = self.velocity/self.velocity * -0.1
# #             #print 'v =', self.velocity
# #             self.position += self.target * (self.velocity * last_time)
#
#     def move(self):
#         self.position += self.target
#
#     def rotatex(self, rate):
#         start = time.time()
#         while self.rotatingx:
#             self._rotatex(rate/(time.time()-start))
#             start = time.time()
#             stackless.schedule()
#
#     def stopx(self, args):
#         self.rotatingx = False
#
#     def stopy(self, args):
#         self.rotatingy = False
#
#     def _rotatex(self, angle):
#         angle *= self.piover180
#         up = self.up[:]
#         target = self.target[:]
#         cosBeta  = math.cos(angle)
#         cosAlpha = math.cos(self.piover2 - angle)
#         self.up.x = cosBeta * up.x + cosAlpha * target.x
#         self.up[1] = cosBeta * up[1] + cosAlpha * target[1]
#         self.up[2] = cosBeta * up[2] + cosAlpha * target[2]
#         cosAlpha = math.cos(self.piover2 + angle)
#         self.target.x = cosBeta * target.x + cosAlpha * up.x
#         self.target[1] = cosBeta * target[1] + cosAlpha * up[1]
#         self.target[2] = cosBeta * target[2] + cosAlpha * up[2]
#
#     def rotatey(self, angle):
#         target = self.target[:]
#         right = self.right[:]
#         angle *= self.piover180
#         cosAlpha = math.cos(self.piover2 + angle)
#         cosBeta = math.cos(angle)
#         self.target.x = (cosBeta * target.x + cosAlpha * right.x)
#         self.target[1] = (cosBeta * target[1] + cosAlpha * right[1])
#         self.target[2] = (cosBeta * target[2] + cosAlpha * right[2])
#         cosAlpha = math.cos(self.piover2 - angle)
#         self.right.x = (cosAlpha * target.x + cosBeta * right.x)
#         self.right[1] = (cosAlpha * target[1] + cosBeta * right[1])
#         self.right[2] = (cosAlpha * target[2] + cosBeta * right[2])
#         #self.target.normalise()
#         #self.right.normalise()
#
#     def rotatez(self):
#         rotating = True
#         while rotating:
#             print 'rotate'
#             start = time.time()
#             rotating = self.channels['z'].receive()
#             self._rotatez(rate/(time.time()-start))
#
#     def _rotatez(self, angle):
#         up = self.up[:]
#         right = self.right[:]
#         angle *= self.piover180
#         cosAlpha = math.cos(self.piover2 + angle)
#         cosBeta = math.cos(angle)
#         self.right.x = cosAlpha * up.x + cosBeta * right.x
#         self.right[1] = cosAlpha * up[1] + cosBeta * right[1]
#         self.right[2] = cosAlpha * up[2] + cosBeta * right[2]
#         cosAlpha = math.cos(self.piover2 - angle)
#         self.up.x = cosBeta * up.x + cosAlpha * right.x
#         self.up[1] = cosBeta * up[1] + cosAlpha * right[1]
#         self.up[2] = cosBeta * up[2] + cosAlpha * right[2]
#
#     def check_collisions(self, objects):
#         collisions = []
#         for name, vector in objects:
#             if abs(self.position.x - vector.x) < 6 and \
#                abs(self.position.y - vector.y) < 6 and \
#                abs(self.position[2] - vector[2]) < 6:
#                 difference = position-vector
#                 if difference.magnitude_squared() < 36:
#                     collisions.append(name)
#         return collisions

class World(object):
    def __init__(self, size, objects):
        self.objects = objects

    def check_collisions(self):
        pass
